
/***********************************************
 *  Author: Matt Fontaine
 *  
 *  Purpose: This class writes data to csv files
 *           that can be read in excel to generate
 *           line graphs for the data. It doesn't
 *           care what kind of data but calculates
 *           average, std dev, and 95% confidence.
 *           It saves the data for each generation
 *           and the data represents the combined
 *           for multiple runs.
 *            
 **********************************************/


import java.io.*;
import java.util.*;

public class CSVDataWriter
{
   PrintWriter outputWriter;
   ArrayList<Double>[] data;
   int numGens;

   public CSVDataWriter(int numGens, String filename)
   {
      // Create a growable array for our data
      this.numGens = numGens;
      data = new ArrayList[numGens];
      for (int i=0; i<numGens; i++)
         data[i] = new ArrayList<Double>();

      // Create a print writer to write our data
      try
      {
         outputWriter = new PrintWriter(new File(filename));
      } 
      catch (FileNotFoundException e)
      {
         e.printStackTrace();
      }
   }

   void addDatum(int generationNumber, double value)
   {
      // Lets add a datum to our data
      data[generationNumber].add(value);
   }

   void close()
   {
      // Here we write our findings to the output file
      // To do this we go through each generation to make
      // a line in our data file, also we add a header
      outputWriter.println("Generation,Average,Standard Deviation,Confidence Interval Low, Confidence Interval High");
      for (int curGen=0; curGen<numGens; curGen++)
      {
         // First calculate the average of the data
         int numValues = data[curGen].size();
         double sum = 0.0;
         for (double val : data[curGen])
            sum += val;
         double avg = sum/numValues;
         
         // Make another pass to compute the top half of standard 
         // deviation which is a sum of squares value
         double avgSquared = 0.0;
         for (double val : data[curGen])
         {
            double diff = val-avg;
            avgSquared += diff*diff;
         }

         // Now calculate the variance, standard deviation and 
         // the 95% confidence interval
         double variance = avgSquared/(numValues-1);
         double stddev = Math.sqrt(variance);
         double lo = avg - 1.96*stddev;
         double hi = avg + 1.96*stddev;
      
         // Now that we have our data add a line to our csv file for this run
         outputWriter.printf("%d,%.4f,%.4f,%.4f,%.4f%n",curGen,avg,stddev,lo,hi);
      }
   
      outputWriter.close();
   }
}
